package com.asianrapid.core.utils;

import org.apache.commons.io.output.FileWriterWithEncoding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Auther: 迟家鑫
 * @Date: 2018/6/19 13:42
 * @Description:文件保存工具类
 */
public class FileUtils {

    protected static Logger logger = LoggerFactory.getLogger(FileUtils.class);

    /**
     * 文件分隔符
     */
    private static final String FILE_SEPARATOR = File.separator;

    /**
     * 从路径中获取文件名。
     *
     * @param path 路径
     * @return 文件名
     */
    public static String getFileName(String path) {
        int i = path.lastIndexOf(FILE_SEPARATOR);
        if (i == -1) {
            return path;
        }
        return path.substring(i + 1);
    }

    /**
     * 从路径获取文件保存的目录路径。
     *
     * @param path 路径
     * @return 文件名路径
     */
    public static String getFilePath(String path) {
        int i = path.lastIndexOf(FILE_SEPARATOR);
        if (i == -1) {
            return path;
        }
        return path.substring(0, path.lastIndexOf(FILE_SEPARATOR));
    }

    /**
     * 从路径中获取所有文件的文件名。
     *
     * @param path 路径
     * @return 文件名
     */
    public static String[] getFileListName(String path) {
        File file = new File(path);
        file.list();
        return file.list();
    }

    /**
     * 功能：复制文件或者文件夹。
     *
     * @param inputFile   源文件
     * @param outputFile  目的文件
     * @param isOverWrite 是否覆盖(只针对文件)
     * @throws IOException
     */
    public static void copy(File inputFile, File outputFile, boolean isOverWrite)
            throws IOException {
        if (!inputFile.exists()) {
            throw new RuntimeException(inputFile.getPath() + "源目录不存在!");
        }
        copyPri(inputFile, outputFile, isOverWrite);
    }

    /**
     * 功能：为copy 做递归使用。
     *
     * @param inputFile
     * @param outputFile
     * @param isOverWrite
     * @throws IOException
     */
    private static void copyPri(File inputFile, File outputFile,
                                boolean isOverWrite) throws IOException {
        // 是个文件。
        if (inputFile.isFile()) {
            copySimpleFile(inputFile, outputFile, isOverWrite);
        } else {
            // 文件夹
            if (!outputFile.exists()) {
                outputFile.mkdir();
            }
            // 循环子文件夹
            for (File child : inputFile.listFiles()) {
                copy(child,
                        new File(outputFile.getPath() + "/" + child.getName()),
                        isOverWrite);
            }
        }
    }

    /**
     * 功能：copy单个文件
     *
     * @param inputFile   源文件
     * @param outputFile  目标文件
     * @param isOverWrite 是否允许覆盖
     * @throws IOException
     */
    private static void copySimpleFile(File inputFile, File outputFile,
                                       boolean isOverWrite) throws IOException {
        // 目标文件已经存在
        if (outputFile.exists()) {
            if (isOverWrite) {
                if (!outputFile.delete()) {
                    throw new RuntimeException(outputFile.getPath() + "无法覆盖！");
                }
            } else {
                // 不允许覆盖
                return;
            }
        }
        InputStream in = new FileInputStream(inputFile);
        OutputStream out = new FileOutputStream(outputFile);
        byte[] buffer = new byte[1024];
        int read = 0;
        while ((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }
        in.close();
        out.close();
    }

    /**
     * 文件作成. <br>
     *
     * @param filename 文件名
     * @throws IOException
     */
    public static void createFile(String filename) throws IOException {
        File file = null;
        try {
            createDirectory(filename);
            file = new File(filename);
            if (!file.exists()) {
                file.createNewFile();
                logger.info("文件(createFile):" + file.getPath() + "已作成");
            }
        } catch (IOException ioe) {
            logger.error("createFile Error:" + ioe.getMessage());
        } finally {
            file = null;
        }
    }

    /**
     * 通过信息生成本地的文件
     *
     * @param messageSingle 要存储的信息，每个元素单独存储一行
     * @param fileName      文件绝对路径
     */
    public static void createLoaclFile(List<String> messageSingle, String fileName) {
        FileWriter fw = null;
        BufferedWriter bw = null;
        try {
            //生成本地文件
            createFile(fileName);
            fw = new FileWriter(fileName);
            bw = new BufferedWriter(fw);
            for (String string : messageSingle) {
                bw.write(string);
                bw.newLine();
            }
            bw.newLine();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 通过信息生成本地的文件(信贷数据准备)
     *
     * @param messageSingle 要存储的信息
     * @param fileName      文件绝对路径
     * @throws IOException
     */
    public static void createLoaclSCMSFile(List<String> messageSingle, String fileName) {
        FileWriterWithEncoding fw = null;
        BufferedWriter bw = null;
        try {
            //生成本地文件
            createFile(fileName);
            fw = new FileWriterWithEncoding(fileName, "GBK");//oracle使用gbk编码格式
            bw = new BufferedWriter(fw);
            for (String string : messageSingle) {
                //将UTF-8转化为GBK
//    			String stringGbk = UrlUtil.encode(string, "UTF-8");
                bw.write(string);
                bw.newLine();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 文件路径的作成. <br>
     *
     * @param path 文件路径
     */
    public static void createDirectory(String path) {
        logger.debug("path:" + path);
        String pathBef = "";
        if (path.indexOf(File.separator) == 0) {
            pathBef = path.substring(0, 2);
            path = path.substring(2);
            pathBef = pathBef + path.substring(0, path.indexOf(File.separator) + 1);
        } else {
            pathBef = path.substring(0, path.indexOf(File.separator) + 1);
        }
        path = path.substring(path.indexOf(File.separator) + 1);
        int index = 0;
        File dir = null;
        while (path.indexOf(File.separator, index) > 0) {
            index = path.indexOf(File.separator, index) + 1;
            String curPath = pathBef + path.substring(0, index);
            dir = new File(curPath);
            if (!dir.exists()) {
                dir.mkdir();
            }
        }
    }

    /**
     * 删除文件. <br>
     *
     * @param filename 文件名
     */
    public static boolean deleteFile(String filename) {
        File file = new File(filename);
        if (file == null || !file.exists()) {
            logger.info("文件:" + file.getPath() + "不存在");
            return false;
        }
        if (file.exists()) {
            file.delete();
            logger.info("文件:" + file.getPath() + "正常删除");
        }
        return true;
    }


    /**
     * 文件是否存在. <br>
     *
     * @param path 文件路径
     * @return true 存在, <br>
     * false 不存在
     */
    public static boolean isExist(String path) {
        File file = new File(path);
        boolean blnFlg = file.exists();
        return blnFlg;
    }

    /**
     * 删除文件夹及其子文件. <br>
     *
     * @param path 文件夹路径
     */
    public static boolean deleteDirectory(String path) {
        File file = null;
        try {
            file = new File(path);
            if (file == null || !file.exists()) {
                logger.info("文件夹:" + file.getPath() + "不存在");
                return true;
            }
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                if (files[i].isDirectory() && files[i].listFiles().length > 0) {
                    deleteDirectory(files[i].getPath());
                }
                boolean delFlg = false;
                if (files[i].canWrite()) {
                    delFlg = files[i].delete();
                }
                if (!delFlg) {
                    logger.error("文件夹:" + files[i].getPath() + "删除失败");
                    return false;
                }
                logger.debug("文件:" + files[i].getPath() + "正常删除");
            }
            return file.delete();
        } catch (SecurityException ioe) {
            logger.error("deleteDirectory Error1:" + ioe.getMessage());
            return false;
        } finally {

            file = null;
        }
    }

    /**
     * 解析并读取txt文件 <br>
     * 分隔符为|+|
     *
     * @param path 文件路径
     */
    public static List<Map<Integer, Object>> getTxtFileInfo(String path) {
        List<Map<Integer, Object>> retList = new ArrayList<Map<Integer, Object>>();
        logger.debug("path:" + path);
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            String str = "";
            fis = new FileInputStream(path);
            // 从文件系统中的某个文件中获取字节
            isr = new InputStreamReader(fis);
            br = new BufferedReader(isr);
            while ((str = br.readLine()) != null) {
                Map<Integer, Object> map = new HashMap<Integer, Object>();
                if (!StringUtils.isEmpty(str)) {
                    int index = 1;
                    for (String obj : str.split("\\|\\+\\|")) {
                        map.put(index, StringUtils.trim(obj));
                        index++;
                    }
                    retList.add(map);
                }
            }
        } catch (FileNotFoundException e) {
            System.out.println("找不到指定文件");
        } catch (IOException e) {
            System.out.println("读取文件失败");
        } finally {
            try {
                br.close();
                isr.close();
                fis.close();
                // 关闭的时候最好按照先后顺序关闭最后开的先关闭所以先关s,再关n,最后关m
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return retList;
    }

    /**
     * 解析并读取核心的txt文件 <br>
     * 分隔符为    (核心传递过来的文件)
     *
     * @param path 文件路径
     */
    public static List<Map<Integer, Object>> getCoreTxtFileInfo(String path) {
        List<Map<Integer, Object>> retList = new ArrayList<Map<Integer, Object>>();
        logger.debug("path:" + path);
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            String str = "";
            fis = new FileInputStream(path);
            // 从文件系统中的某个文件中获取字节
            isr = new InputStreamReader(fis);
            br = new BufferedReader(isr);
            while ((str = br.readLine()) != null) {
                Map<Integer, Object> map = new HashMap<Integer, Object>();
                if (!StringUtils.isEmpty(str)) {
                    int index = 1;
                    for (String obj : str.split("")) {
                        map.put(index, StringUtils.trim(obj));
                        index++;
                    }
                    retList.add(map);
                }
            }
        } catch (FileNotFoundException e) {
            System.out.println("找不到指定文件");
        } catch (IOException e) {
            System.out.println("读取文件失败");
        } finally {
            try {
                br.close();
                isr.close();
                fis.close();
                // 关闭的时候最好按照先后顺序关闭最后开的先关闭所以先关s,再关n,最后关m
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return retList;
    }

}
